﻿using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using System.ComponentModel;
using System.Xml.Linq;

namespace EasyXaf.LowCode.WorkflowEditors.Models.Activities;

[DomainComponent]
public abstract class Branch : Sequence, IBranch
{
    public static IEnumerable<ITypeInfo> BranchTypeInfos { get; }

    [Browsable(false)]
    public string Label
    {
        get => GetPropertyValue<string>();
        set => SetPropertyValue(value);
    }

    [Browsable(false)]
    public string Comment
    {
        get => GetPropertyValue<string>();
        set => SetPropertyValue(value);
    }

    [XafDisplayName("表达式")]
    public string Expression
    {
        get => GetPropertyValue<string>();
        set => SetPropertyValue(value);
    }

    [Browsable(false)]
    public virtual string ImageName { get; }

    [Browsable(false)]
    public virtual string Color { get; } = "#2980B9";

    [Browsable(false)]
    public NodeViewMode ViewMode
    {
        get => GetPropertyValue<NodeViewMode>();
        set => SetPropertyValue(value);
    }

    [Browsable(false)]
    public double TitleViewScale
    {
        get => GetPropertyValue<double>();
        set => SetPropertyValue(value);
    }

    [Browsable(false)]
    public double DetailViewScale
    {
        get => GetPropertyValue<double>();
        set => SetPropertyValue(value);
    }

    [Browsable(false)]
    public virtual bool HasDetailView => false;

    [Browsable(false)]
    public bool IsSelected { get; set; }

    [Browsable(false)]
    public virtual bool AllowSelect => false;

    [Browsable(false)]
    public abstract bool AllowMove { get; }

    [Browsable(false)]
    public virtual bool AllowScale => true;

    [Browsable(false)]
    public virtual bool AllowCopy => false;

    [Browsable(false)]
    public abstract bool AllowDelete { get; }

    [Browsable(false)]
    public virtual bool AllowValidate => true;

    [Browsable(false)]
    public IActivity Activity { get; }

    public override IContainer Container => Activity.Container;

    public event EventHandler<bool> SelectionChanged;

    string INode.Caption
    {
        get => Label;
        set => Label = value;
    }

    public Branch(IWorkflow workflow, IActivity activity)
        : base(workflow)
    {
        Activity = activity;
        TitleViewScale = 1.0;
        DetailViewScale = 1.5;
    }

    static Branch()
    {
        BranchTypeInfos = XafTypesInfo.Instance.PersistentTypes
            .Where(t => typeof(IBranch).IsAssignableFrom(t.Type))
            .Where(t => !t.IsAbstract && !t.IsInterface)
            .Where(t => t.Type.GetConstructor(new Type[] { typeof(IWorkflow), typeof(IActivity) }) != null)
            .ToList();
    }

    public override void WriteStateToXml(XElement element)
    {
        base.WriteStateToXml(element);

        SetXmlValue(element, nameof(Label), Label);
        SetXmlValue(element, nameof(Comment), Comment);
        SetXmlValue(element, nameof(Expression), Expression);
        SetXmlValue(element, nameof(ViewMode), ViewMode);
        SetXmlValue(element, nameof(TitleViewScale), TitleViewScale);
        SetXmlValue(element, nameof(DetailViewScale), DetailViewScale);
    }

    public override void ReadStateFromXml(XElement element)
    {
        base.ReadStateFromXml(element);

        Label = GetXmlValue<string>(element, nameof(Label));
        Comment = GetXmlValue<string>(element, nameof(Comment));
        Expression = GetXmlValue<string>(element, nameof(Expression));
        ViewMode = GetXmlValue<NodeViewMode>(element, nameof(ViewMode));
        TitleViewScale = GetXmlValue<double>(element, nameof(TitleViewScale));
        DetailViewScale = GetXmlValue<double>(element, nameof(DetailViewScale));
    }
}
